package com.ms.oschina.api.remote;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.MultipartBody.Part;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Request.Builder;
import okhttp3.RequestBody;
import okhttp3.Response;

import com.ms.oschina.api.cookie.CookiesManager;
import com.ms.oschina.base.AppContext;
import com.ms.oschina.bean.HttpResponse;
import com.ms.oschina.task.NetXMLParseTask;
import com.ms.oschina.util.LogUtils;
import com.ms.oschina.util.UiUtils;

/**
 * Created by zhy on 15/8/17.
 */
public class OkHttpClientManager {
	private static OkHttpClientManager mInstance;
	private OkHttpClient mOkHttpClient;

	public static String API_URL = "http://www.oschina.net/action/api/%s";

	public static final MediaType JSON = MediaType
			.parse("application/json; charset=utf-8");
	public static final MediaType Form = MediaType
			.parse("application/x-www-form-urlencoded; charset=utf-8");
	public static final MediaType textPlain = MediaType
			.parse("text/plain; charset=utf-8");
	private static final String TAG = "OkHttpClientManager";

	private OkHttpClientManager() {
		mOkHttpClient = new OkHttpClient().newBuilder()
				.cookieJar(new CookiesManager()).build();
	}

	private Builder getRequestBuilder() {
		return new Request.Builder().addHeader("User-Agent",
				ApiClientHelper.getUserAgent(AppContext.getInstance()));
	}
	

	public static OkHttpClientManager getInstance() {
		if (mInstance == null) {
			synchronized (OkHttpClientManager.class) {
				if (mInstance == null) {
					mInstance = new OkHttpClientManager();
				}
			}
		}
		return mInstance;
	}

	/**
	 * 同步的Get请求
	 * 
	 * @param url
	 * @return Response
	 */
	public Response getSync(String url) throws IOException {
		url = String.format(API_URL, url);
		LogUtils.d("url:" + url);
		Request request = getRequestBuilder().url(url).build();
		Call call = mOkHttpClient.newCall(request);
		Response execute = call.execute();
		return execute;
	}

	/**
	 * 异步的Get请求,并解析xml数据
	 * 
	 * @param <T>
	 * 
	 * @param url
	 * @return 解析的xml数据
	 */
	public <T> void getAsyncAsString(String url, int requestCode,
			Class<T> clazz, OnGetNetResultListener<T> listener) {
		NetXMLParseTask<Class<T>> task = new NetXMLParseTask(
				url, requestCode, clazz, listener);
		task.execute();
	}

	/**
	 * 同步的Get请求
	 * 
	 * @param url
	 * @return 字符串
	 */
	public String getSyncAsString(String url) throws IOException {
		Response execute = getSync(url);
		return execute.body().string();
	}

	/**
	 * POST提交Json数据
	 * 
	 * @param url
	 * @param json
	 * @return
	 * @throws IOException
	 */
	public String postJson(String url, String json) throws IOException {
		url = String.format(API_URL, url);
		RequestBody body = RequestBody.create(JSON, json);
		Request request = getRequestBuilder().url(url).post(body).build();
		Response response = mOkHttpClient.newCall(request).execute();
		if (response.isSuccessful()) {
			return response.body().string();
		} else {
			throw new IOException("Unexpected code " + response);
		}
	}

	/**
	 * POST同步提交数据
	 * 
	 * @param url
	 * @param cookie
	 * @return
	 * @throws IOException
	 */
	public String postSyncAsString(String url, RequestBody body)
			throws IOException {
		Response response = postSync(url, body);
		if (response.isSuccessful()) {
			return response.body().string();
		} else {
			throw new IOException("Unexpected code " + response);
		}
	}

	/**
	 * POST同步提交数据
	 * 
	 * @param url
	 * @param cookie
	 * @return Response
	 * @throws IOException
	 */
	public Response postSync(String url, RequestBody body) throws IOException {
		url = String.format(API_URL, url);
		Request request = getRequestBuilder().url(url).post(body).build();
		Response response = mOkHttpClient.newCall(request).execute();
		if (response.isSuccessful()) {
			return response;
		} else {
			throw new IOException("Unexpected code " + response);
		}
	}

	/**
	 * 异步get请求方式
	 */
	public void OKdoGet(String url, Callback callback) {
		url = String.format(API_URL, url);
		final Request request = getRequestBuilder().url(url).build();
		// new call
		Call call = mOkHttpClient.newCall(request);
		call.enqueue(callback);
	}

	/**
	 * 异步post请求方式
	 */
	public void OKdoPost(String url, RequestBody body, Callback callback) {
		url = String.format(API_URL, url);

		Request request = getRequestBuilder().url(url).post(body).build();
		mOkHttpClient.newCall(request).enqueue(callback);
	}

	public String getCookie(String path) {
		// 得到cookie 并保存cookie
		CookieJar cookieJar = getCookieJar();
		HttpUrl url = HttpUrl.parse(path);
		List<Cookie> cookies = cookieJar.loadForRequest(url);
		StringBuilder sb = new StringBuilder();
		for (Cookie cookie : cookies) {
			sb.append(cookie.toString());
			sb.append(";");
		}
		return sb.toString();
	}

	public CookieJar getCookieJar() {
		return mOkHttpClient.cookieJar();
	}

	public interface OnGetNetResultListener<T> {
		public abstract void onGetNetResult(int requestCode,
				HttpResponse<T> result);
	}

}